package FamilyTherapy;

import java.util.ArrayList;
import java.util.Random;

public class Game 
{
	private int noOfPlayer;
	private int dice;
	
	private int decisionMakerNo;

	private Board board;	
	private ArrayList<Integer> EventCardArray;
	private ArrayList<Integer> SayActCardArray;
	private ArrayList<Integer> MagicToolArray;
		
	public Game()
	{
		noOfPlayer=0;
		dice=0;
		int cardNo = 20;
		board= new Board();
		
		generateCards(cardNo);
	}
	
	public void setNoOfPlayer(int number)
	{		
		noOfPlayer=number;
	}
	
	public int getNoOfPlayer()
	{
		return noOfPlayer;
	}
	
	public void startGame(GCWindow gcWindow, Player p[])
	{
		GCWindow.outputStr("Game start!!!\n");
		gcWindow.displayAllInfo(p);
	}
	
	public void gameLoop(GCWindow gcWindow, Player p[])
	{		
		boolean isEndGame = false; 
		char dummy;
		
		while(!isEndGame){
			for(int i=0;i<getNoOfPlayer()&&!isEndGame;i++){
				gcWindow.displayPlayerInfo(p[i]);
				
				GCWindow.inputChar("Player " + i+ ", please enter \"r\" for rolling dice : \n");
				
				dice = rollDice();
				
				move(i,dice,p);
				checkPosition(gcWindow,i,p); 
				
				gcWindow.displayPlayerInfo(p[i]);
				
				if(p[i].getPoint()>3)
					sharePoint(i,p);
				
				if(p[i].getPoint() >= 10) {
					isEndGame = true;
					endGame(gcWindow,i,p);
				}
			}				
		}
	}
	
	private int rollDice()
	{
		Random randomGenerator = new Random();
		return randomGenerator.nextInt(5)+1; //If 6, range is from 0 to 6.
	}
	
	private void move(int currentPlayerNo,int dice, Player p[])
	{
		p[currentPlayerNo].setPosition(p[currentPlayerNo].getPosition()+dice);
		 GCWindow.outputStr(p[currentPlayerNo].getName() + ", you are in square [" + p[currentPlayerNo].getPosition() + "].\n");
	}
	
	private void checkPosition(GCWindow gcWindow,int currentPlayerNo, Player p[])
	{ 
		int currentPlayerPos;
		int currentEvent;
		currentPlayerPos = p[currentPlayerNo].getPosition();
	
		currentEvent = board.getBox(currentPlayerPos);
		
		switch(currentEvent)
		{
			case 1: 
				drawEvent(gcWindow, currentPlayerNo,p); 
				break; 
			case 2: 
				drawMT(currentPlayerNo, p); 
				break;
			case 3: 
				drawSA(gcWindow, currentPlayerNo, p); 
				break;
			default:
				break;
		}		
	}
	
	
	public void endGame(GCWindow gcWindow,int currentPlayerNo,Player p[])
	{	
		 GCWindow.outputStr("Game ended!\n" +
				"The Winner is: Player " + currentPlayerNo + " : " + 
				p[currentPlayerNo].getName() + "!!!\n" +
				"Congratulations!!!!!!!!\n");		
	}
	
	private void sharePoint(int currentPlayerNo,Player p[])
	{ 		
		boolean shareTrigger = false; 
		for(int i=0; i<getNoOfPlayer(); i++)
		{
			if(i!=currentPlayerNo && p[i].getPoint()<3) 
				shareTrigger = true;
		}
		
		if(shareTrigger && p[currentPlayerNo].getPoint()>3)
		{
			char share='n'; //Edited by Sing in 3/6/2012 ////String share="null"; ->char share='n';
			int shareTarget = currentPlayerNo;
			boolean repeat = true;
			int pt =1;
					
			share = GCWindow.inputChar("Player " + currentPlayerNo + 
					", do you share your SE point to other players?\n"+
					"Please enter \"y\" or \"n\" :\n");
			
			
			if(share =='y' || share =='Y')
			{
				while(repeat)
				{
					repeat = true;
					GCWindow.outputStr("Player " + currentPlayerNo+ ", Which player do you want to share?\n");
					
					GCWindow.outputStr("Target : \n"); 
					for(int j=0;j<getNoOfPlayer();j++)
					{
						if(j!=currentPlayerNo && p[j].getPoint()<3)
							GCWindow.outputStr(p[j].getName()+ " , player no: " + j+"\n");  //Edited by Sing in 3/6/2012 
					}
										
					while (shareTarget<0 || shareTarget>=p.length||shareTarget==currentPlayerNo) {
						GCWindow.outputStr("Which one: ");

						shareTarget=GCWindow.inputInt(0, p.length, "NULL");
						
						if(shareTarget==currentPlayerNo)
							GCWindow.outputStr("You cannot share to yourself.\n");
					} 
					
					
					if(shareTarget!=currentPlayerNo &&  p[shareTarget].getPoint()<3
						&& shareTarget< noOfPlayer && shareTarget>=0)
						repeat = false;
				}
				p[currentPlayerNo].deductPoint(pt);
				p[shareTarget].addPoint(pt);
				GCWindow.outputStr("SE Point Receiver: " + p[shareTarget].getName() + ", you got " + pt + " mark added.\n" );
				GCWindow.outputStr("SE Point Donor: " + p[currentPlayerNo].getName() + ", you got " + pt + " mark deducted.\n" );
			}
		}
	}
	
	private void drawEvent(GCWindow gcWindow, int currentPlayerNo, Player p[])
	{
		int choice=0;
		int receiveVariable=0;
		
		Random randomGenerator = new Random();
		EventCard currentEvent = new EventCard(randomGenerator.nextInt(noOfPlayer));
		GCWindow.outputStr(currentEvent.getDescription()+"\n");
		currentEvent.displayChoiceDescription(); 
		decisionMakerNo = currentEvent.getDecisionMaker()%noOfPlayer;
		GCWindow.outputStr("The decision maker is: " + p[decisionMakerNo].getName()+"\n");
			
		choice=GCWindow.inputInt(Main.decisionMin, Main.decisionMax, "Please input your decision (1-4): ");
				
		int useMTNum = gcWindow.requestUsingMT(currentPlayerNo,p);
		
		if(p[currentPlayerNo].getHoldingCard().size()!=0 && useMTNum != -1)//solved by adding useMTNum !=-1 
		{
			MagicToolCard magic = new MagicToolCard();
			receiveVariable = magic.switchMT(useMTNum, currentEvent, choice, currentPlayerNo, p, decisionMakerNo);
			p[currentPlayerNo].deductHoldingCard(useMTNum);
			MagicToolArray.remove(MagicToolArray.size()-1);
		}
		
		if(receiveVariable == -1) {
			GCWindow.outputStr("no point has been deducted.\n");
		}
		else {
			//the below function is included with deduct mark
			p[currentPlayerNo].addPoint(currentEvent.getPoint(choice-1));
		}
		
	}
	
	private void generateCards(int cardNo)
	{
		EventCardArray = new ArrayList<Integer>(); 
		SayActCardArray = new ArrayList<Integer>(); 
		MagicToolArray = new ArrayList<Integer>(); 
		
		for(int i=0;i<cardNo;i++){			
			Random randomGenerator = new Random();
			EventCardArray.add(randomGenerator.nextInt(5)); //Bug report: nextInt(5)+1 -> nextInt(4)+1 -> (5)
			Random randomGenerator2 = new Random();
			SayActCardArray.add(randomGenerator2.nextInt(5));
			Random randomGenerator3 = new Random();
			MagicToolArray.add(randomGenerator3.nextInt(5));
		}		
	}
	
	private void drawSA(GCWindow gcWindow, int currentPlayerNo, Player p[])
	{
		SayActCard currentSA = new SayActCard(SayActCardArray.get(SayActCardArray.size()-1)); 
		GCWindow.outputStr(currentSA.getDescription()+"\n");
		currentSA.displayDescription();
		gcWindow.requestUsingSA(currentSA, currentPlayerNo, p);
		SayActCardArray.remove(SayActCardArray.size()-1);
	}
	
	private void drawMT(int currentPlayerNo, Player p[])
	{
		GCWindow.outputStr("You have drawn the : " + MagicToolCard.magicCard[MagicToolArray.get(MagicToolArray.size()-1)]);
		p[currentPlayerNo].addHoldingCard(MagicToolArray.get(MagicToolArray.size()-1));
	}
	
}
